﻿// -----------------------------------------------------------------------
// <copyright file="LocatorServiceHostFactory.cs" company="Henadzi Sabaleuski.">
// Copyright (c) Henadzi Sabaleuski. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

namespace OCM.Enterprise.OCR.Utilities.Unity
{
	#region Usings

	using System;
	using System.ServiceModel;
	using System.ServiceModel.Activation;

	using Microsoft.Practices.Unity;
	using Microsoft.Practices.Unity.Configuration;

	#endregion

	/// <summary>
	/// Represents a <see cref="ServiceHostFactory"/> which uses Service Locator pattern for the Dependency Injection purposes.
	/// </summary>
	public class LocatorServiceHostFactory : ServiceHostFactory, IDisposable
	{
		#region Private Fields

		/// <summary>
		/// The <see cref="UnityContainer"/> field which used as container for the Service Locator.
		/// </summary>
		private readonly UnityContainer unityContainer;

		/// <summary>
		/// The <see cref="UnityServiceLocator"/> field which used for Dependency Injection purposes.
		/// </summary>
		private readonly UnityServiceLocator serviceLocator;

		/// <summary>
		/// Represents the disposing state of the object.
		/// </summary>
		private bool disposed = false;

		#endregion

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="LocatorServiceHostFactory"/> class.
		/// </summary>
		public LocatorServiceHostFactory()
		{
			this.unityContainer = new UnityContainer();
			this.unityContainer.LoadConfiguration();

			this.serviceLocator = new UnityServiceLocator(this.unityContainer);
		}

		#endregion

		#region IDisposable Members

		/// <summary>
		/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
		/// </summary>
		public void Dispose()
		{
			this.Dispose(true);

			GC.SuppressFinalize(this);
		}

		#endregion

		#region ServiceHostFactory Overrides

		/// <summary>
		/// Creates a <see cref="T:System.ServiceModel.ServiceHost"/> for a specified type of service with a specific base address.
		/// </summary>
		/// <param name="serviceType">Specifies the type of service to host.</param>
		/// <param name="baseAddresses">The <see cref="T:System.Array"/> of type <see cref="T:System.Uri"/> that contains the base addresses for the service hosted.</param>
		/// <returns>
		/// A <see cref="T:System.ServiceModel.ServiceHost"/> for the type of service specified with a specific base address.
		/// </returns>
		protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
		{
			return new LocatorServiceHost(this.serviceLocator, serviceType, baseAddresses);
		}

		#endregion

		#region Protected Implementation

		/// <summary>
		/// Releases unmanaged and - optionally - managed resources
		/// </summary>
		/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
		protected virtual void Dispose(bool disposing)
		{
			if (!this.disposed)
			{
				if (disposing)
				{
					if (this.serviceLocator != null)
					{
						this.serviceLocator.Dispose();
					}

					if (this.unityContainer != null)
					{
						this.unityContainer.Dispose();
					}
				}
			}

			this.disposed = true;
		}

		#endregion
	}
}